﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

using DR.Repository.Abstract;
using DR.WebUI.Models.Manager;
using DR.WebUI.Models.Enums;
using DR.DBDomainModel;
using DR.WebUI.Code;
using Omu.Awesome.Core;


namespace DR.WebUI.Controllers
{
    [Authorize(Roles = "TopManager,manager")]
    public class ManagerController : Controller
    {
        public int PageSize { get; set; }
        private readonly IReportRepository _reportRepository;
        private readonly IReportingPeriodRepository _reportingPeriodRepository;
        private readonly IProjectRepository _projectRepository;
        private readonly IDeveloperRepository _developerRepository;
        private readonly IDeveloperProjectRepository _developerProjectRepository;

        public ManagerController(
            IReportRepository reportRepository, 
            IReportingPeriodRepository reportingPeriodRepository,
            IProjectRepository projectRepository, 
            IDeveloperRepository developerRepository,
            IDeveloperProjectRepository developerProjectRepository)
        {
            _reportRepository = reportRepository;
            _reportingPeriodRepository = reportingPeriodRepository;
            _projectRepository = projectRepository;
            _developerRepository = developerRepository;
            _developerProjectRepository = developerProjectRepository;
            PageSize = 15;
        }

        public ActionResult Menu()
        {
            return View();
        }

        [HttpGet]
        public ViewResult ReportsOverview(ReportFilter filter, int page = 1)
        {
            IList<ReportingPeriod> reportingPeriods = _reportingPeriodRepository.SelectAll();

            if (!filter.ReportingPeriodID.HasValue)
            {
                filter.ReportingPeriodID = GetDefaultReportingPeriodID(reportingPeriods);
            }

            IList<Report> reports = _reportRepository
                .SelectByFilter(filter.ReportingPeriodID, filter.ProjectID, filter.DeveloperID, filter.SelectedReportStatuses);
            IList<ReportsOverviewModel> reportsOverviewModels = reports
                .Select(r => new ReportsOverviewModel
                {
                    ReportID = r.ReportID,
                    Project = r.DeveloperProject.Project.Name,
                    Developer = r.DeveloperProject.Developer.Name,
                    ReportTitle = r.Title,
                    DateReporting = r.DateReporting,
                    Hours = r.Hours,
                    State = (ReportStatus)r.State,
                    DateCreate = r.DateCreate,
                })
                .ToList();            

            IList<SelectListItem> reportingPeriodListItems = reportingPeriods
                .OrderBy(r => r.DateStart)
                .Select(r => new SelectListItem
                                {
                                    Value = r.ReportingPeriogID.ToString(),
                                    Text = string.Format("{0} - {1}{2}", r.DateStart.ToShortDateString(), r.DateFinish.ToShortDateString(), r.IsFinished ? " (closed)" : ""),
                                    Selected = (r.ReportingPeriogID == filter.ReportingPeriodID)
                                })
                .ToList();

            ViewData["ReportingPeriods"] = reportingPeriodListItems;

            IList<Project> projects = _projectRepository.SelectAll();
            IList<SelectListItem> projectItems = projects
                .OrderBy(r => r.Name)
                .Select(r => new SelectListItem { Text = r.Name, Value = r.ProjectID.ToString(), Selected = (r.ProjectID == filter.ProjectID) })
                .ToList();
            if (projectItems.Count > 0)
            {
                projectItems.Insert(0, new SelectListItem { Value = "", Text = "All", Selected = !filter.ProjectID.HasValue });
            }

            ViewData["Projects"] = projectItems;

            IList<Developer> developers = _developerRepository.SelectAll();
            IList<SelectListItem> developerItems = developers
                .OrderBy(r => r.Name)
                .Select(r => new SelectListItem { Value = r.DeveloperID.ToString(), Text = r.Name, Selected = (r.DeveloperID == filter.DeveloperID) })
                .ToList();
            developerItems.Insert(0, new SelectListItem { Value = "", Text = "All", Selected = !filter.DeveloperID.HasValue });

            ViewData["Developers"] = developerItems;

            ViewData["ReportStatuses"] = MiscHelpers.GetAllFilterReportStatuses();

            ViewData["ReportFilter"] = filter;

            return View("ReportsOverview", new Pageable<ReportsOverviewModel>
                                               {
                                                   PageIndex = page,
                                                   PageCount = MiscHelpers.GetPageCount(PageSize, reportsOverviewModels.Count),
                                                   Page = reportsOverviewModels.Skip((page - 1) * PageSize).Take(PageSize)
                                              });            
        }

        private int? GetDefaultReportingPeriodID(IList<ReportingPeriod> reportingPeriods)
        {            
            ReportingPeriod currentReportingPeriod = reportingPeriods
                .Where(r => !r.IsFinished)
                .OrderBy(r => r.DateStart)
                .FirstOrDefault();
            return currentReportingPeriod != null ? (int?)currentReportingPeriod.ReportingPeriogID : null; 
        }

        public ViewResult TaskView(int page)
        {
            var projects = _projectRepository.SelectAll();
            IList<SelectListItem> projectItems = projects
                .OrderBy(r => r.Name)
                .Select(r => new SelectListItem { Text = r.Name, Value = r.ProjectID.ToString() })
                .ToList();

            projectItems.Insert(0, new SelectListItem { Value = "", Text = "", Selected = true});
            IList<SelectListItem> list = new List<SelectListItem> {new SelectListItem {Text = "", Value = ""}};

            ViewData["ProjectsItems"] = projectItems;
            ViewData["DeveloperItems"] = list;

            IList<ReportsOverviewModel> reportsOverviewModels = _reportRepository.SelectAll().Select(r => new ReportsOverviewModel
                                                                    {
                                                                        ReportID = r.ReportID,
                                                                        Project = r.DeveloperProject.Project.Name,
                                                                        Developer = r.DeveloperProject.Developer.Name,
                                                                        ReportTitle = r.Title,
                                                                        DateReporting = r.DateReporting,
                                                                        Hours = r.Hours,
                                                                        State = (ReportStatus)r.State,
                                                                        ReportDescription = r.Description,
                                                                        Description = r.Description,
                                                                        DateCreate = r.DateCreate,
                                                                    })
                                                                    .ToList();


            return View(new Pageable<ReportsOverviewModel>
            {
                PageIndex = page,
                PageCount = MiscHelpers.GetPageCount(PageSize, reportsOverviewModels.Count),
                Page = reportsOverviewModels.Skip(--page * PageSize).Take(PageSize)
            });
        }

        [HttpPost]
        public JsonResult ChangeState(int id, ReportStatus state)
        {
            _reportRepository.ChangeState(id, Convert.ToInt32(state));

            return Json(new { result = "ok" });
        }

        #region Task
        [HttpPost]
        public JsonResult CreateNewTask(ReportModel model)
        {
            ReportingPeriod reportingPeriod = _reportingPeriodRepository.SelectAll().FirstOrDefault(n => n.IsFinished == false);
            DeveloperProject firstOrDefault = _developerProjectRepository.SelectAll().FirstOrDefault(n => n.DeveloperID == model.DeveloperID && n.ProjectID == model.ProjectID);

            _reportRepository.Insert(new Report
                                      {
                                          Title = model.Title,
                                          Description = model.Decsriprion,
                                          Hours = 0,
                                          State = (int)ReportStatus.Pending,
                                          DateCreate = DateTime.Now,
                                          ReportingPeriodID = reportingPeriod.ReportingPeriogID,
                                          DeveloperProjectID = firstOrDefault.DeveloperProjectID
                                      });

            return Json(new { result = true });
        }

        [HttpPost]
        public JsonResult EditTask(ReportModel model)
        {
            ReportingPeriod reportingPeriod = _reportingPeriodRepository.SelectAll().FirstOrDefault(n => n.IsFinished == false);
            DeveloperProject firstOrDefault = _developerProjectRepository.SelectAll().FirstOrDefault(n => n.DeveloperID == model.DeveloperID && n.ProjectID == model.ProjectID);
            Report reportEnity = _reportRepository.SelectAll().FirstOrDefault(n => n.ReportID == model.ID);

            var report = new Report
                                {
                                    ReportID = model.ID,
                                    Title = model.Title,
                                    Description = model.Decsriprion,
                                    Hours = reportEnity.Hours,
                                    State = reportEnity.State,
                                    DateCreate = reportEnity.DateCreate,
                                    DateModified = DateTime.Now,
                                    ReportingPeriodID = reportingPeriod.ReportingPeriogID,
                                    DeveloperProjectID = firstOrDefault.DeveloperProjectID
                                };

            _reportRepository.Update(report);

            return Json(new { result = true });
        }

        public JsonResult DeveloperWithProject(int projctID)
        {
            IEnumerable<int> enumerable = _developerProjectRepository.SelectAll().Where(n => n.ProjectID == projctID).Select(n => n.DeveloperID).ToList();

            var projectItems = enumerable
                            .Select(i => _developerRepository
                            .SelectAll()
                            .FirstOrDefault(n => n.DeveloperID == i))
                            .Select(firstOrDefault => new SelectListItem
                                                          {
                                                              Text = firstOrDefault.Name,
                                                              Value = firstOrDefault.DeveloperID.ToString()
                                                          }).ToList();


            return Json(new { result = true, data = projectItems });
        } 
        #endregion

        [HttpPost]
        public ActionResult SetupReportFilter(int? reportingPeriodID, int? projectID, int? developerID, string filterButton, ReportFilter filter)
        {
            if (filterButton == "Apply")
            {
                filter.ReportingPeriodID = reportingPeriodID;
                filter.ProjectID = projectID;
                filter.DeveloperID = developerID;
            }
            else if (filterButton == "Reset")
            {
                ReportFilter defaultFilter = new ReportFilter();

                filter.ReportingPeriodID = GetDefaultReportingPeriodID(_reportingPeriodRepository.SelectAll());

                filter.ProjectID = defaultFilter.ProjectID;
                filter.DeveloperID = defaultFilter.DeveloperID;
            }
            return ReportsOverview(filter);
        }

        
    }
}
